import { cookies } from "next/headers"; import { NextResponse, type NextRequest } from "next/server"; import { COOKIE, verifyToken } from "@/lib/auth"; export const dynamic = "force-dynamic"; const API_URL = process.env.API_URL ?? "http://127.0.0.1:8350"; const API_TOKEN = process.env.SRC_API_TOKEN ?? ""; /** Authenticated pass-through to the control-plane API (adds the server token, streams SSE as-is). */ async function forward(req: NextRequest, path: string[]) { const jar = await cookies(); if (!verifyToken(jar.get(COOKIE)?.value)) return NextResponse.json({ error: "unauthorized" }, { status: 401 }); const target = new URL(`/api/${path.join("/")}`, API_URL); target.search = req.nextUrl.search; const headers: Record = { "x-src-token": API_TOKEN }; if (req.headers.get("content-type")) headers["content-type"] = req.headers.get("content-type")!; const upstream = await fetch(target, { method: req.method, headers, body: req.method === "GET" || req.method === "HEAD" ? undefined : await req.text(), cache: "no-store", // @ts-expect-error — undici option for streaming request bodies duplex: "half" }); const ct = upstream.headers.get("content-type") ?? "application/json"; return new Response(upstream.body, { status: upstream.status, headers: { "content-type": ct, "cache-control": "no-store", ...(ct.includes("event-stream") ? { connection: "keep-alive", "x-accel-buffering": "no" } : {}) } }); } export async function GET(req: NextRequest, ctx: { params: Promise<{ path: string[] }> }) { return forward(req, (await ctx.params).path); } export async function POST(req: NextRequest, ctx: { params: Promise<{ path: string[] }> }) { return forward(req, (await ctx.params).path); }